package pt.ua.helpdesk.server;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import persistence.Assistant;
import persistence.Command;
import persistence.Comment;
import persistence.Person;
import persistence.Ticket;
import pt.ua.helpdesk.client.ServicePerformance;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class ServicePerformanceImpl extends RemoteServiceServlet implements ServicePerformance 
{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private Float milliToHours(long milli)
	{
		long hours = milli/3600000;
		return new Float(hours);
	}
	
	public ArrayList getAssistants()
	{
		ArrayList<Object> Assistants = new ArrayList<Object>();
		ArrayList<Object> idAssis = new ArrayList<Object>();
		ArrayList<Object> names = new ArrayList<Object>();
		
		ArrayList<Integer> par = new ArrayList<Integer>();
		
		par.add(new Integer(1));//Active
		
		List<Assistant> l = (List<Assistant>)Command.select("select a from Assistant a where (a.active = ?1)", par);
		for(int i = 0; i < l.size(); i++)
		{
			idAssis.add(new Integer(l.get(i).getIdperson()));
			names.add(new String(l.get(i).getName()));
		}
			
		Assistants.add(idAssis);
		Assistants.add(names);
		
		return Assistants;
		
	}
	
	public ArrayList getAssisPerformance(Integer idAssis)
	{
		ArrayList perform = new ArrayList();
		ArrayList<Object> idTickets = new ArrayList<Object>();	
		String sql;
		long sumtempo = 0, media = 0;
		int n = 0,nassigned = 0, nsolved = 0, nsolving = 0, i;
		
		Person p = (Person) Command.find(Person.class, idAssis);
		
		//Tickets atribuidos 0
		ArrayList par1 = new ArrayList();
		par1.add(p);
		par1.add(new Integer(1)); //Ticket active
	
		
		sql = "select t from Ticket t, Comment c where ((t = c.refidticket) and (c.refidpersonAuthor = ?1) and (t.active = ?2))";
		List<Ticket> l = (List<Ticket>)Command.select(sql, par1);
	
		for(i = 0; i < l.size(); i++)
		{
			/* Este if serve para resolver o problema do JQL não suportar
			 * a clausula distinct*/
			if(idTickets.contains(l.get(i).getIdticket()) == false)
			{
				idTickets.add(new Integer(l.get(i).getIdticket()));
				nassigned++;
				if(l.get(i).getStatus() == 2)
				{
					nsolving++;
				}
				else if(l.get(i).getStatus() == 3)
				{
					nsolved++;
				}
				
			}
		}
		ArrayList par2 = new ArrayList();
		Assistant a = (Assistant)Command.find(Assistant.class, idAssis);
		par2.add(a);
		
		par2.add(new Integer(1)); //Ticket active
		
		sql = "select t from Ticket t, Assignment a where ((a.assistant = ?1) and (t.active = ?2) and (t = a.ticket))";
		/* Duas listas pk o JQL não suporta UNION
		 * */
		List<Ticket> l2 = (List<Ticket>)Command.select(sql, par2);
	
		for(i = 0; i < l2.size(); i++)
		{
			nassigned++;
		}
		
		perform.add(new Integer(nassigned));
		
		perform.add(new Integer(nsolved));
		perform.add(new Integer(nsolving));
		//Media de resolução 3
		ArrayList par4 = new ArrayList();
		par4.add(new Integer(1)); //active
		par4.add(new Integer(3)); //solved
		par4.add(p); //solved
		sql = "select c from Ticket t, Comment c where ((t.active = ?1) and (t.status = ?2) and (t = c.refidticket) and (c.refidpersonAuthor = ?3))";
		List<Comment> commentsList  = (List<Comment>)Command.select(sql, par4);
		for(n = 0; n < commentsList.size(); n++)
		{
			Date endDate = commentsList.get(n).getDate();
			Date startDate = commentsList.get(n).getRefidticket().getDate();
			sumtempo += (endDate.getTime() - startDate.getTime());
		}
		
		if(n != 0)
		{
			media = sumtempo/n;
			Float mean = milliToHours(media);
			perform.add(mean);
		}
		else
		{
			perform.add(new Float(0));
		}
		
		return perform;
	}
	
	public ArrayList getOverAllPerformance()
	{
		ArrayList perform = new ArrayList();
		ArrayList par1 = new ArrayList();
		String sql;
		long sumtempo = 0, media;
		int n = 0;

		//pedidos efectuados 0
		par1.add(new Integer(1)); //Active
		sql = "select COUNT(t) from Ticket t where (t.active = ?1)";
		List<Integer> l1 = (List<Integer>)Command.select(sql, par1);
		if(l1.size() > 0)
		{
			perform.add(l1.get(0));
		}

		//pedido pendente 1
		ArrayList par2 = new ArrayList();
		par2.add(new Integer(1)); //pendente active
		sql = "select COUNT(t) from Ticket t where ((t.active = ?1) and (t.status = ?1))";
		List<Integer> l2 = (List<Integer>)Command.select(sql, par2);
		if(l2.size() > 0)
		{
			perform.add(l2.get(0));
		}
	
		//pedidos resolvido 2
		ArrayList par3 = new ArrayList();
		par3.add(new Integer(1)); //active
		par3.add(new Integer(3)); //solved
		//par3.add(new Date())
		sql = "select t from Ticket t where ((t.active = ?1) and (t.status = ?2))";
		List<Ticket> ticketList = (List<Ticket>)Command.select(sql, par3);
		if(l2.size() > 0)
		{
			perform.add(ticketList.size());
		}

		//Media de resolução 3
		ArrayList par4 = new ArrayList();
		par4.add(new Integer(1)); //active
		par4.add(new Integer(3)); //solved
		sql = "select c from Ticket t, Comment c where ((t.active = ?1) and (t.status = ?2) and (t = c.refidticket))";
		List<Comment> commentsList  = (List<Comment>)Command.select(sql, par4);
		for(n = 0; n < commentsList.size(); n++)
		{
			Date endDate = commentsList.get(n).getDate();
			Date startDate = commentsList.get(n).getRefidticket().getDate();
			sumtempo += (endDate.getTime() - startDate.getTime());
		}
		
		media = n!=0 ? (sumtempo/n) : 0;
		Float mean = milliToHours(media);
		perform.add(mean);

		//nr de user 4
		ArrayList par5 = new ArrayList();
		par5.add(new Integer(1)); //validados
		sql = "select COUNT(u) from Utilizador u where (u.valid = ?1)";
		List<Integer> l5 = (List<Integer>)Command.select(sql, par5);
		if(l2.size() > 0)
		{
			perform.add(l5.get(0));
		}

		return perform;
	}
	
}
